#include "dal.h"
#include "string.h"
#include "stdlib.h"




MYSQL* InitMySQL(MYSQL* mysql){
	return mysql_init(mysql);
}

void CloseMySQL(MYSQL* mysql){
	mysql_close(mysql);
}

MYSQL* ConnectToMySQL(MYSQL* mysql,const char* host,const char* user,const char* passwd,const char* db,unsigned int port){
	return mysql_real_connect(mysql,host,user,passwd,db,port,NULL,CLIENT_MULTI_STATEMENTS);
}

QueryResultList* DoQuery(MYSQL* mysql,const char* query){
	
	QueryResultList* list = (QueryResultList*)malloc(sizeof(QueryResultList));
	list->head = NULL;
	list->length = 0;
	QueryResult* cur = NULL;

	mysql_query(mysql,query);

	do{
		MYSQL_RES* res;
		res= mysql_store_result(mysql);
		
		QueryResult* r = (QueryResult*)malloc(sizeof(QueryResult));
		r->result = NULL;
		r->msg = NULL;
		r->affected_rows = 0;
		r->type = sets;
		r->next = NULL;
		r->error_no = 0;

		if ( cur == NULL ){
			cur = r;
			list->head = cur;
		}
		else{
			cur->next = r;
			cur = cur->next;
		}

		if ( res ){
			unsigned int row,col;
			MYSQL_ROW record;
			MYSQL_FIELD *fields;
			fields = mysql_fetch_fields(res);
			col = mysql_num_fields(res);
			row = mysql_num_rows(res);
			r->col = col;
			r->row = row;
			r->affected_rows = row;
			r->result = (char**)malloc(sizeof(char*)*(col*(row+1)));
			
			unsigned int i;
			for(i=0;i<col;i++){
				r->result[i] = (char*)malloc((strlen(fields[i].name)+1)*sizeof(char));
				strcpy(r->result[i],fields[i].name);
			}
			int rw = 1;
			while((record = mysql_fetch_row(res))) {
				for(i = 0;i<col;i++){
					if ( record[i] != NULL ){
						r->result[rw*col+i] = (char*)malloc((strlen(record[i])+1)*sizeof(char));
						strcpy(r->result[rw*col+i],record[i]);
					}
					else{
						r->result[rw*col+i] = NULL;
					}
				}
				++rw;
			}
		}
		else{
			GetExecuteQueryInfo(mysql,r);
		}
		list->length++;

		mysql_free_result(res);
	}while (!mysql_next_result(mysql));

	return list;
}

QueryResultList* DoQuery(MYSQL* mysql,const char* query,QueryResultList* list,QueryResult* cur,QueryResult* r){
	
	/*QueryResultList* list = (QueryResultList*)malloc(sizeof(QueryResultList));
	list->head = NULL;
	list->length = 0;*/
	//QueryResult* cur = NULL;

	mysql_query(mysql,query);

	do{
		MYSQL_RES* res;
		res= mysql_store_result(mysql);
		
		/*QueryResult**/ r = (QueryResult*)malloc(sizeof(QueryResult));
		r->result = NULL;
		r->msg = NULL;
		r->affected_rows = 0;
		r->type = sets;
		r->next = NULL;
		r->error_no = 0;

		if ( cur == NULL ){
			cur = r;
			list->head = cur;
		}
		else{
			cur->next = r;
			cur = cur->next;
		}

		if ( res ){
			unsigned int row,col;
			MYSQL_ROW record;
			MYSQL_FIELD *fields;
			fields = mysql_fetch_fields(res);
			col = mysql_num_fields(res);
			row = mysql_num_rows(res);
			r->col = col;
			r->row = row;
			r->affected_rows = row;
			r->result = (char**)malloc(sizeof(char*)*(col*(row+1)));
			
			unsigned int i;
			for(i=0;i<col;i++){
				r->result[i] = (char*)malloc((strlen(fields[i].name)+1)*sizeof(char));
				strcpy(r->result[i],fields[i].name);
			}
			int rw = 1;
			while((record = mysql_fetch_row(res))) {
				for(i = 0;i<col;i++){
					if ( record[i] != NULL ){
						r->result[rw*col+i] = (char*)malloc((strlen(record[i])+1)*sizeof(char));
						strcpy(r->result[rw*col+i],record[i]);
					}
					else{
						r->result[rw*col+i] = NULL;
					}
				}
				++rw;
			}
		}
		else{
			GetExecuteQueryInfo(mysql,r);
		}
		list->length++;

		mysql_free_result(res);
	}while (!mysql_next_result(mysql));

	return list;
}

QueryResult* GetExecuteQueryInfo(MYSQL* mysql,QueryResult* r){
	if ( r == NULL)
		r = (QueryResult*)malloc(sizeof(QueryResult));
	r->msg = NULL;
	r->next = NULL;
	r->result = NULL;
	unsigned int err_no = mysql_errno(mysql);
	if(err_no == 0){
		r->type = affectedrows;
		const char* info = mysql_info(mysql);
		if ( info ){
			r->msg = (char*)malloc((strlen(info)+1)*sizeof(char));                     
			strcpy(r->msg,info);
		}
		else
			r->affected_rows = mysql_affected_rows(mysql);
	}
	else{
		r->type = error;
		r->error_no = err_no;
		const char* errmsg = mysql_error(mysql);
		r->msg = (char*)malloc((strlen(errmsg)+1)*sizeof(char));                   
		strcpy(r->msg,errmsg);
	}
	return r;
}

void FreeQueryResultList(QueryResultList* res){
	QueryResult* r = res->head;
	QueryResult* tmp;
	while ( r ){
		tmp = r;
		r = r->next;
		FreeQueryResult(tmp);
	}
	free(res);
}

void FreeQueryResult(QueryResult* r){
	if ( r == NULL )
		return;
	if ( r->result ){
		for (int i=0; i < (r->col)*(r->row+1); ++i)
			if ( r->result[i] )
				free(r->result[i]);
		free(r->result);
	}
	if ( r->msg )
		free(r->msg);
	free(r);
}

